package cz.zcu.sefler.mois.data;

import java.io.IOException;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import javax.servlet.ServletOutputStream;

import cz.zcu.sefler.mois.data.model.Monitor;
import cz.zcu.sefler.mois.data.model.Sentence;

/**
 * Trida ZipOutputer zajistuje prevedeni dat z DB do zip souboru.
 * 
 * @author Vojtech Sefler
 * 
 */
public class ZipOutputer {

  MonitorDAO monitorDao;

  public ZipOutputer(String machine, String db, String user, String pass) {
    this.monitorDao = new MonitorDAO(machine, db, user, pass);
  }

  /**
   * Metoda do proudu v parametru vlozi zip soubor se vsemi vetami.
   * 
   * @param sos
   *          Proud, do ktereho zip soubor potece, v nasem pripade servlet.
   * @return
   */
  public void getAllSentencesZip(ServletOutputStream sos) throws IOException, SQLException {
    ZipOutputStream zout = new ZipOutputStream(sos);

    /* Ziskam vety z databaze. */
    ArrayList<Sentence> sentences = monitorDao.getAllSentences();

    /*
     * Nyni pridam jednu vetu po druhe do zip souboru. Kazda veta se nachazi v
     * samostatnemi XML souboru.
     */
    for (Sentence sentence : sentences) {
      /* Jmeno XML souboru je pojmenovano dle identifikatoru vety. */
      zout.putNextEntry(new ZipEntry(String.valueOf(sentence.getId()) + ".xml"));

      /* Zapis vety v prislusnem kodovani. */
      zout.write(("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + getSingleSentenceXml(sentence, "")).getBytes("UTF-8"));

      zout.closeEntry();

    }

    zout.flush();
    zout.close();
  }

  /**
   * Metoda do proudu v parametru vlozi zip soubor se vsemi rozhovory - vcetne
   * jejich vet.
   * 
   * @param sos
   *          Stream, do ktereho zip soubor potece, v nasem pripade servlet.
   */
  public void getAllMonitorsZip(ServletOutputStream sos) throws IOException, SQLException {
    ZipOutputStream zout = new ZipOutputStream(sos);

    /* Ziskani monitoru z databaze. */
    ArrayList<Monitor> monitors = monitorDao.getMonitors();

    for (Monitor monitor : monitors) {
      /* Jmeno XML souboru je pojmenovano dle identifikatoru rozhovoru. */
      zout.putNextEntry(new ZipEntry(String.valueOf(monitor.getId()) + ".xml"));

      /* Zapis monitoru v prislusnem kodovani. */
      zout.write(("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + getSingleMonitorXml(monitor)).getBytes("UTF-8"));
      zout.closeEntry();
    }
    zout.flush();
    zout.close();
  }

  /**
   * Tato metoda vytvori z rozhovoru XML retezec, ktery tento rozhovor
   * reprezentuje.
   * 
   * @param monitor
   *          Rozhovor, ktery prevedeme do formy XML.
   * @return XML daneho rozhovoru.
   */
  private String getSingleMonitorXml(Monitor monitor) {
    /* Adresa rozhovoru */
    String monitorXml = "<interview url=\"" + monitor.getUrl() + "\">\n";

    /* Jednotlive vety rozhovoru. */
    for (Sentence sentence : monitor.getListSentences()) {
      monitorXml += getSingleSentenceXml(sentence, "  ");
    }
    monitorXml += "</interview>\n";

    return monitorXml;
  }

  /**
   * Tato metoda vytvori z vety XML retezec, ktery tuto vetu reprezentuje.
   * 
   * @param sentence
   *          Veta, kterou prevedu do formy XML.
   * @param indent
   *          Odsazeni vnoreneho XML elementu.
   * @return
   */
  private String getSingleSentenceXml(Sentence sentence, String indent) {
    /* Identifikator vety. */
    String sentenceXml = indent + "<sentence id=\"" + sentence.getId() + "\">\n";

    /* Typ vety. */
    sentenceXml += indent + "  <type>\n";
    sentenceXml += indent + "    " + sentence.getType() + "\n";
    sentenceXml += indent + "  </type>\n";

    /* Textovy obsah vety. */
    sentenceXml += indent + "  <content>\n";
    sentenceXml += indent + "    " + sentence.getContent() + "\n";
    sentenceXml += indent + "  </content>\n";

    sentenceXml += indent + "</sentence>\n";

    return sentenceXml;
  }
}
